/*
 * @Author: zzy 917106840648 NJUST
 * @Date: 2020-03-24 08:55:51
 * @LastEditTime: 2020-04-04 21:09:04
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \W+compiler\SyntacticAnalyzer.cpp
 */
#include "..\include\SyntacticAnalyzer.h"

ifstream input_SyntacticInput("SyntacticInput.txt");
ifstream input_LexicalOutput("LexicalOutput.txt");
ifstream input_Token("TOKEN.txt");
ofstream output_ACTION;
ofstream output_GOTO;
ofstream output_FIRST;
ofstream output_PARSER;
// set<char> Item::final;  // 全局静态变量
// set<char> Item::unFinal;
// set<char> Item::allSymbol;

int delimiterNumS = 9;

//界符
const char delimiterS[20] = {',', '(', ')', '{', '}', ';'};  //界符

string stringCut(const string input, int i, int j)
{
    return string(input.begin() + i, input.begin() + j);
}

string char2string(char a)
{
    string       statetemp;
    stringstream sstream;
    sstream << a;
    statetemp = sstream.str();
    sstream.str("");
    return statetemp;
}

/**
 * @description: show 产生式
 * @param {type}
 * @return:
 */
void Production::show()
{
    cout << production_to_string() << endl;
}

/**
 * @description: 将产生式转化为 string
 * @param {type}
 * @return:
 */
string Production::production_to_string()
{
    string output = string(1, proBegin) + "->" + proEnd;
    int    i      = 0;

    set<char>::iterator it = additionalSymbol.begin();
    for (; it != additionalSymbol.end(); it++) {
        if ((*it) != '#') {
            output += string(1, (i == 0 ? ',' : '|')) + (*it);
            i++;
        }
    }
    if (additionalSymbol.find('#') != additionalSymbol.end()) {
        output += string(1, i++ == 0 ? ',' : '|') + "#";
    }
    return output;
}

Production::Production(const string& input)
{
    proBegin = input[0];
    proEnd   = input.substr(3, input.length() - 3);
}

/**
 * @description: 添加新的项目集
 * @param {type}
 * @return:
 */
void Item::addItem(const string& input)
{
    int i = 0;
    int j = 0;

    if (input.length() < 4) {
        cout << "Error Item::addItem()--length<4" << endl;
        return;
    }

    char unFinalTemp;

    //判断是否为 产生式
    if (stringCut(input, 1, 3) == "->" && isupper(input[0])) {
        unFinalTemp = input[0];
    }
    else {
        cout << "Error Item::addItem()--不为产生式" << endl;
        return;
    }

    for (i = 0; i < input.length(); i++) {
        char temp = input[i];
        if (isupper(temp)) {
            unFinal.insert(temp);
            allSymbol.insert(temp);
        }
        else {
            if (temp != '|' && !(temp == '-' && input[i + 1] == '>' && ++i)) {
                final.insert(temp);
                allSymbol.insert(temp);
            }
        }
    }

    for (i = 3; i < input.length(); i++) {
        for (j = i + 1; (j < input.length()) && (input[j] != '|'); ++j)
            ;
        Production pro =
            Production(string(1, unFinalTemp) + "->" + stringCut(input, i, j));

        if (find(production.begin(), production.end(), pro) ==
            production.end()) {
            production.push_back(pro);
        }
        i = j;
    }
}

/**
 * @description:展示项目集
 * @param {type}
 * @return:
 */
void Item::show()
{
    vector<Production>::iterator it = production.begin();
    for (; it != production.end(); it++) {
        (*it).show();
    }
}

/**
 * @description:展示 终结符 非终符
 * @param {type}
 * @return:
 */
void Item::showFinal()
{
    // static set<char>   unFinal;     //非终结符
    // static set<char>   final;       //终结符
    // static set<char>   allSymbol;   //终结符 非终结符并集
    cout << "unFinal : ";
    set<char>::iterator itunF = unFinal.begin();
    for (; itunF != unFinal.end(); itunF++) {
        cout << (*itunF) << " ";
    }
    cout << endl;

    cout << "Final : ";
    set<char>::iterator itF = final.begin();
    for (; itF != final.end(); itF++) {
        cout << (*itF) << " ";
    }
    cout << endl;
}

/**
 * @description: 添加Item
 * @param {type}
 * @return:
 */
void Lr::addItem(string s)
{
    G.addItem(s);
}

/**
 * @description: 从文件中读取 到 输入栈
 * @param {type}
 * @return:
 */
void Lr::getInputStack(string input)
{
    //此处可以使用文件读入形式
    // input_file
    // cout << "读入 输入栈" << endl;
    inputStack.push_back('#');
    stateStack.push_back(0);
    for (int i = input.length() - 1; i >= 0; i--) {
        inputStack.push_back(input[i]);
    }

    //获取 行数
    string inToken;
    string temp;
    int    line;
    lineStack.push_back(0);
    while (getline(input_Token, inToken)) {
        // cout << inToken << endl;
        temp = stringCut(inToken, 7, 9);
        line = stoi(stringCut(inToken, 1, 3));
        // cout << "line : " << line << endl;
        if (temp == ">=" || temp == "<=" || temp == "==" || temp == "&&" ||
            temp == "||" || temp == "+=" || temp == "-=") {
            lineStack.push_back(line);
            lineStack.push_back(line);
        }
        else {
            lineStack.push_back(line);
        }
    }

    reverse(lineStack.begin(), lineStack.end());

    vector<int>::iterator it = lineStack.begin();
    for (; it != lineStack.end(); it++) {
        // cout << *it << endl;
    }
}
/**
 * @description: 展示 输入栈
 * @param {type}
 * @return:
 */
void Lr::showInputStack()
{
    vector<char>::reverse_iterator it = inputStack.rbegin();
    for (; it != inputStack.rend(); ++it) {
        cout << (*it);
        output_PARSER << *it;
    }
}

/**
 * @description: 展示状态栈
 * @param {type}
 * @return:
 */
void Lr::showStateStack()
{
    vector<int>::iterator it = stateStack.begin();
    for (; it != stateStack.end(); it++) {
        cout << *it;
        output_PARSER << *it;
    }
}

/**
 * @description: 展示分析栈
 * @param {type}
 * @return:
 */
void Lr::showAnalyzeStack()
{
    vector<char>::iterator it = analyzeStack.begin();
    for (; it != analyzeStack.end(); it++) {
        cout << *it;
        output_PARSER << *it;
    }
}

/**
 * @description: 1.求得 FIRST 集
 * @param {type}
 * @return:
 */
set<char> Lr::getFirst(string& str)
{
    int i = 0;

    if (str.length() == 0) {  // X->@
        set<char> a;
        a.insert('@');
        return a;
    }
    else if (str.length() == 1) {  // X->a
        //判断是否为终结符
        if (G.final.find(str[0]) != G.final.end() || str[0] == '#') {
            set<char> a;
            a.insert(str[0]);
            return a;
        }
        else if (FIRST[str[0]].size() != 0) {  // X->A
            //判断 FIRST中是否存在 以计算过的 first 集
            return FIRST[str[0]];
        }
        else {
            vector<Production>::iterator it = G.production.begin();
            for (; it != G.production.end(); it++) {
                //查找产生式 右部拥有左部非终结符的产生式
                if ((*it).proBegin == str[0]) {
                    string::size_type isExist =
                        (*it).proEnd.find((*it).proBegin);

                    // if (isExist != string::npos) {
                    //     if (isExist == 0) {  //存在左递归
                    //         continue;
                    //     }
                    //     else {
                    //         string temp = stringCut((*it).proEnd, 0,
                    //         isExist); set<char> a; a.insert('@'); if
                    //         (getFirst(temp) == a) {
                    //             continue;
                    //         }
                    //     }
                    // }

                    set<char> tempF = getFirst((*it).proEnd);

                    // cout << "getFirst : " << (*it).proBegin << endl;
                    FIRST[str[0]].insert(tempF.begin(), tempF.end());
                }
            }
            return FIRST[str[0]];
        }
    }
    else {  // X->ABCD等
        set<char> output;
        for (i = 0; i < str.length(); i++) {
            string    a      = char2string(str[i]);
            set<char> tempFF = getFirst(a);  //逐个符号求 getFirst

            if (tempFF.find('@') != tempFF.end() && str.length() - 1 != i) {
                //若存在 @ 则删除@ 并加入output 并进行 下一个字符的getFirst

                // set<char>::iterator itshow = tempFF.begin();
                //  cout << "getFirst-X1X2X3-可为空 : " << a << "first : ";
                // for (; itshow != tempFF.end(); itshow++) {
                //     cout << *itshow << " ";
                // }
                // cout << endl;

                tempFF.erase(tempFF.find('@'));
                output.insert(tempFF.begin(), tempFF.end());
            }
            else {
                //若tempFF中 没有 @ 或 str 为到最后一位
                // getFirst 完成
                output.insert(tempFF.begin(), tempFF.end());
                break;
            }
        }
        set<char>::iterator outputshow = output.begin();
        // cout << "getFirst-end output : ";
        for (; outputshow != output.end(); outputshow++) {
            // cout << *outputshow << " ";
        }
        // cout << endl;

        return output;
    }
}

/**
 * @description: 2.计算项目集 I 的 e-closure集
 * @param {type}
 * @return:
 */
Item Lr::eclosure(Item I)
{
    // cout << "eclosure--begin" << endl;
    // G.show();
    // cout << "I.show()" << endl;
    // I.show();

    if (I.production.size() == 0) {
        // cout << "Lr eclosure I为空" << endl;
        return I;
    }

    Production pStart = I.production[0];

    int i = 0;
    int j = 0;
    for (i = 0; i < I.production.size(); i++) {
        int ppoint = 0;

        Production ptemp = I.production[i];
        // ptemp.show();

        // Production ptemp=pStart;
        // X->a.B

        if (((ppoint = ptemp.proEnd.find('.')) != string::npos) &&
            (ppoint != ptemp.proEnd.length() - 1) &&
            (G.unFinal.find(ptemp.proEnd[ppoint + 1])) !=
                G.unFinal.end()) {  //确保找到的 '.' 的位置不为 最后 且

            // cout << "ppoint : " << ppoint << endl;

            char a = ptemp.proEnd[ppoint + 1];  //获得产生式右部的 .右边的符号
            // cout << a << endl;
            // if (G.final.find(a) != G.final.end()) {  //若符号a 为终结符
            //     // cout << "unFinal" << endl;
            //     if (a == '@') {  //空
            //         swap(I.production[i].proEnd[ppoint],
            //              I.production[i].proEnd[ppoint + 1]);
            //         continue;
            //     }
            // }
            // cout << "no" << endl;

            // 若为非终结符 则：若项目[A→α·Bβ,a]属于CLOSURE(I)，
            // B→ξ是一个产生式，那么，对于FIRST（βa）中的每一个终结符b，
            //如果[B→·ξ，b]原来不在CLOSURE(I)中，则把它加进去；
            string f =
                stringCut(ptemp.proEnd, ppoint + 2, ptemp.proEnd.length());

            // 求 新的 产生式的每一个终结符b
            // FIRST（βa）中的每一个终结符b，
            set<char> new_additionalSymbol = {};

            set<char>::iterator it = ptemp.additionalSymbol.begin();
            for (; it != ptemp.additionalSymbol.end(); it++) {
                // cout << "for1" << endl;
                string a  = char2string((*it));
                string in = f + a;  // ->f+a 为 所有的 βa
                // cout << in << endl;
                set<char> temp = getFirst(in);
                new_additionalSymbol.insert(temp.begin(), temp.end());
            }

            //将找的的产生加入到项目集
            // cout << G.production.size() << endl;
            for (vector<Production>::iterator itProduction =
                     G.production.begin();
                 itProduction != G.production.end(); ++itProduction) {
                // cout << "for2" << endl;
                if ((*itProduction).proBegin == a) {
                    // cout << "proBegin = " << a << endl;
                    Production temp = *itProduction;
                    if (temp.proEnd[0] == '@') {
                        temp.proEnd = '.' + temp.proEnd;
                        swap(temp.proEnd[0], temp.proEnd[1]);
                    }
                    else {
                        temp.proEnd = '.' + temp.proEnd;
                        // cout << "temp.proEnd : " << temp.proEnd << endl;
                    }

                    // cout << temp.proBegin << "->" << temp.proEnd << endl;

                    //在 I 中搜索是否有相同的 产生式
                    // vector<Production>::iterator itI =
                    //     find(I.production.begin(), I.production.end(), temp);

                    bool isFindInG = false;

                    vector<Production>::iterator itI = I.production.begin();
                    for (; itI != I.production.end(); itI++) {
                        if (((*itI).proBegin == temp.proBegin) &&
                            ((*itI).proEnd == temp.proEnd)) {
                            isFindInG = true;
                            break;
                        }
                    }

                    if (isFindInG) {
                        // cout << temp.proBegin << "->" << temp.proEnd << endl;
                        //若找到相同的产生式，则添加
                        //附加终结符
                        // cout << "same" << endl << endl;
                        itI->additionalSymbol.insert(
                            new_additionalSymbol.begin(),
                            new_additionalSymbol.end());
                    }
                    else {  //若不存在，则添加新的产生式 以及其 附加终结符
                        // cout << "no same" << endl << endl;
                        temp.additionalSymbol.insert(
                            new_additionalSymbol.begin(),
                            new_additionalSymbol.end());
                        I.production.push_back(temp);
                    }
                }
            }
        }
    }
    // I.show();
    // cout << endl;
    // cout << "eclosure--end" << endl;
    return I;
}

/**
 * @description: 3.计算项目集 I 经过 char X后的项目集
 * @param {type}
 * @return: eclosure(J)
 */
Item Lr::Go(Item I, char X)
{
    //根据课本来
    Item J;

    if (I.production.size() == 0 || X == '@') {
        //项目集为空 或@ 返回空项目集
        return J;
    }

    vector<Production>::iterator it = I.production.begin();
    for (; it != I.production.end(); it++) {
        string end    = (*it).proEnd;
        int    ppoint = end.find('.');
        if (end[ppoint + 1] == X) {
            swap(end[ppoint], end[ppoint + 1]);
            // cout << end << endl;
            Production temp =
                Production((*it).proBegin, end, (*it).additionalSymbol);
            J.production.push_back(temp);
        }
    }
    return eclosure(J);
}
/**
 * @description: 4.根据 初始 Item 求项目集 的 DFA
 * @param {type}
 * @return:
 */
void Lr::itemDFA()
{
    // cout << "itemDFA--begin" << endl;

    //设置 $->S,#
    Item begin;

    set<char> symbolBegin;
    symbolBegin.insert('#');
    Production S = Production('$', '.' + char2string(G.production[0].proBegin),
                              symbolBegin);
    S.isEclosure = true;
    begin.production.push_back(S);

    //项目集规范族 添加 初始 $->S,#
    program.push_back(eclosure(begin));

    int size = 0;
    while (size != program.size()) {  //当没有新的项目集加入时 停止
        size = program.size();
        for (int i = 0; i < program.size(); i++) {
            Item temp = program[i];
            for (set<char>::iterator itSymbol = G.allSymbol.begin();
                 itSymbol != G.allSymbol.end(); itSymbol++) {
                // cout << "itemDFA-Go-symbol : " << *itSymbol << endl;
                Item next = Go(temp, (*itSymbol));
                if (next.production.size() != 0) {
                    //判断 项目集规范族中 是否存在 求得的 next
                    vector<Item>::iterator idx =
                        find(program.begin(), program.end(), next);
                    if (idx != program.end()) {
                        //找到了重复的 Item
                        GOTO[make_pair(i, (*itSymbol))] =
                            distance(program.begin(), idx);
                    }
                    else {
                        //没有重复的 Item
                        program.push_back(next);
                        GOTO[make_pair(i, (*itSymbol))] =
                            distance(program.begin(), idx);
                    }
                }
            }
        }
    }
    // cout << "itemDFA--end" << endl;
}

/**
 * @description: 5.构建 ACTION  表
 * @param {type}
 * @return:
 */
void Lr::getAG()
{
    // cout << "getAG--begin" << endl;
    //首先要构建项目集规范族的DFA 此时得到了响应的 GOTO 表
    itemDFA();

    //后面进行构建 ACTION表
    //遍历项目集 规范族

    // S' -> S. ,#
    set<char> symbolBegin;
    symbolBegin.insert('#');
    Production S = Production('$', char2string(G.production[0].proBegin) + '.',
                              symbolBegin);

    for (int i = 0; i < program.size(); i++) {
        //每个项目集
        Item I = program[i];

        vector<Production>::iterator it = I.production.begin();
        //对项目集中的产生式遍历。
        for (; it != I.production.end(); it++) {
            int ppoint = (*it).proEnd.find('.');
            // 圆点 。 不在结尾
            if (ppoint < (*it).proEnd.size() - 1) {
                char X = (*it).proEnd[ppoint + 1];
                //判断 x 是否为终结符 判断GOTO 表中是否存在  I,x
                if (G.final.find(X) != G.final.end() &&
                    GOTO.find(make_pair(i, X)) != GOTO.end()) {
                    //若为终结符，则移进 .ACTION表 划为 shift
                    int temp                = GOTO[make_pair(i, X)];
                    ACTION[make_pair(i, X)] = make_pair(shift, temp);
                }
            }
            // 圆点 。 在结尾
            else {
                // acc
                if ((*it) == S) {
                    ACTION[make_pair(i, '#')] = make_pair(acc, 0);
                }
                else if ((*it).proBegin != '$') {
                    // reduce
                    string temp = (*it).proEnd;
                    temp.erase(ppoint, 1);
                    for (set<char>::iterator addSymbol =
                             (*it).additionalSymbol.begin();
                         addSymbol != (*it).additionalSymbol.end();
                         addSymbol++) {
                        bool isFindInG = false;

                        Production p =
                            Production((*it).proBegin, temp, set<char>{});
                        vector<Production>::iterator itG = G.production.begin();
                        for (; itG != G.production.end(); itG++) {
                            if ((*itG).proBegin == p.proBegin &&
                                (*itG).proEnd == p.proEnd) {
                                isFindInG = true;
                                break;
                            }
                        }
                        if (isFindInG) {
                            ACTION[make_pair(i, (*addSymbol))] = make_pair(
                                reduce, distance(G.production.begin(), itG));
                        }
                    }
                }
            }
        }
    }

    if (G.final.find('@') != G.final.end()) {
        G.final.erase(G.final.find('@'));
        G.allSymbol.erase(G.allSymbol.find('@'));
    }
    G.final.insert('#');
    G.allSymbol.insert('#');
    // cout << "getAG--end" << endl;
    return;
}

/**
 * @description: 6.语法分析的分析过程
 * @param {type}
 * @return:
 */
void Lr::parser()
{
    bool finish = false;
    int  step   = 0;
    cout << "步骤       状态栈        符号栈        输入串       ACTION    "
            "   GOTO      "
         << endl;
    output_PARSER
        << "步骤       状态栈        符号栈        输入串       ACTION    "
           "   GOTO      "
        << endl;
    while (!finish) {
        cout << step << "     ";
        output_PARSER << step << "     ";
        showStateStack();
        cout << "     ";
        output_PARSER << "     ";
        showAnalyzeStack();
        cout << "     ";
        output_PARSER << "     ";
        showInputStack();
        cout << "     ";
        output_PARSER << "     ";

        int stateStackTop = stateStack.size() - 1;
        int inputStackTop = inputStack.size() - 1;

        pair<int, char> temp =
            make_pair(stateStack[stateStackTop], inputStack[inputStackTop]);
        //出错
        if (ACTION.find(temp) == ACTION.end()) {
            cout << "Syntactic Error" << endl;
            output_PARSER << "Syntactic Error" << endl;
            getError();
            break;
        }
        pair<actionState, int> actionTemp = ACTION[temp];
        //移进
        if (actionTemp.first == shift) {
            cout << "SHIFT-->" << actionTemp.second;
            output_PARSER << "SHIFT-->" << actionTemp.second;

            stateStack.push_back(actionTemp.second);
            analyzeStack.push_back(inputStack[inputStackTop]);
            inputStack.pop_back();
            // cout << " line : " << lineStack.back();
            // cout << "  input end : " << inputStack.back();
            // cout << "  analyzeStack end : " << analyzeStack.back();
            lineStack.pop_back();
        }
        else if (actionTemp.first == reduce) {
            //规约
            Production p = G.production[actionTemp.second];
            cout << "REDUCE-->" << actionTemp.second << " : " << p.proBegin
                 << "->" << p.proEnd;
            output_PARSER << "REDUCE-->" << actionTemp.second << " : "
                          << p.proBegin << "->" << p.proEnd;

            if (p.proEnd != "@") {
                //从状态栈 和 分析栈 中 自栈顶向下去掉r个字符 （r 为A->X
                // X的长度）， 并把A移入到分析栈中，再把满足
                // SJ=GOTO[SI,A]的状态移入状态栈
                for (int i = 0; i < p.proEnd.size(); i++) {
                    stateStack.pop_back();
                    analyzeStack.pop_back();
                }
            }
            //输出 新增状态
            cout << "    "
                 << GOTO[make_pair(stateStack[stateStack.size() - 1],
                                   p.proBegin)];
            output_PARSER << "    "
                          << GOTO[make_pair(stateStack[stateStack.size() - 1],
                                            p.proBegin)];

            analyzeStack.push_back(p.proBegin);
            stateStack.push_back(
                GOTO[make_pair(stateStack[stateStack.size() - 1], p.proBegin)]);
        }
        else if (actionTemp.first == acc) {
            finish = true;

            cout << "ACC" << endl;
            output_PARSER << "ACC" << endl;
        }
        step++;

        cout << endl << endl;
        output_PARSER << endl << endl;
    }
    if (finish) {
        cout << "YES" << endl;
        output_PARSER << "YES" << endl;
    }
    else {
        cout << "NO";
        output_PARSER << "NO";
    }
}

/**
 * @description: 7.错误分析
 * @param {type}
 * @return:
 */
void Lr::getError()
{
    cout << "ErrorLine -> " << lineStack.back() << endl;
    output_PARSER << "ErrorLine -> " << lineStack.back() << endl;
    //简单纠错
    char x = analyzeStack.back();
    char y = inputStack.back();
    cout << "x : " << x << " y : " << y << endl;
    // x 为 分析栈最后一位  y 为 输入栈 最后一位

    if (x == 't' && y == 'y') {
        cout << "Error -> 缺少标识符" << endl;
        output_PARSER << "Error -> 缺少标识符" << endl;
    }
    if (x == 'z' && y == 't') {
        cout << "Error -> 缺少;" << endl;
        output_PARSER << "Error -> 缺少;" << endl;
    }
    if (x == 'z' && y == 'f') {
        cout << "Error -> 缺少;" << endl;
        output_PARSER << "Error -> 缺少;" << endl;
    }
    if (x == 'z' && y == 'w') {
        cout << "Error -> 缺少;" << endl;
        output_PARSER << "Error -> 缺少;" << endl;
    }
    if (x == 'y' && y == 'w') {
        cout << "Error -> 缺少;" << endl;
        output_PARSER << "Error -> 缺少;" << endl;
    }
    if (x == 'y' && y == 'f') {
        cout << "Error -> 缺少;" << endl;
        output_PARSER << "Error -> 缺少;" << endl;
    }
    if (x == 'z' && y == 'z') {
        cout << "Error -> 缺少;或," << endl;
        output_PARSER << "Error -> 缺少;或," << endl;
    }
    if (x == 'z' && y == 'y') {
        cout << "Error -> 缺少运算符" << endl;
        output_PARSER << "Error -> 缺少运算符" << endl;
    }
    if (x == 'y' && y == 't') {
        cout << "Error -> 缺少;" << endl;
        output_PARSER << "Error -> 缺少;" << endl;
    }
    if (x == 'y' && y == 'z') {
        cout << "Error -> 缺少算术运算符或;或," << endl;
        output_PARSER << "Error -> 缺少算术运算符或;或," << endl;
    }
    if (x == 'y' && y == 'y') {
        cout << "Error -> 缺少算术运算符" << endl;
        output_PARSER << "Error -> 缺少算术运算符" << endl;
    }

    if (x != 't' && x != 'z' && x != 'y' && !isDelimiterS(x) && y != 't' &&
        y != 'z' && y != 'y' && !isDelimiterS(y)) {
        cout << "Error -> 多余运算符" << y << endl;
        output_PARSER << "Error -> 多余运算符" << y << endl;
    }

    if (x != 't' && x != 'z' && x != 'y' && !isDelimiterS(x) &&
        isDelimiterS(y)) {
        cout << "Error -> 缺少常数或标识符或)" << endl;
        output_PARSER << "Error -> 缺少常数或标识符或)" << endl;
    }

    if (y != 't' && y != 'z' && y != 'y' && !isDelimiterS(y) &&
        isDelimiterS(x)) {
        if (y == '#') {
            cout << "Error -> 缺少 } " << endl;
            output_PARSER << "Error -> 缺少 } " << endl;
        }
        else {
            cout << "Error -> 缺少常数或标识符或 ( " << endl;
            output_PARSER << "Error -> 缺少常数或标识符或 ( " << endl;
        }
    }
}

/**
 * @description: LR运行
 * @param {type}
 * @return:
 */
void Lr::run()
{
    string in;
    while (getline(input_SyntacticInput, in) && in != "#")
        addItem(in);
    in = "";

    // G.show();
    // cout << endl;
    // cout << "getAG : " << endl;
    getAG();

    showAFG();

    // cout << endl << "input : " << endl;
    getline(input_LexicalOutput, in);
    if (in == "#" || in.size() == 0)
        return;

    // cout << "input_LexicalOutput" << endl;
    getInputStack(in);
    parser();
}

/**
 * @description: 展示 FIRST ACTION GOTO
 * @param {type}
 * @return:
 */
void Lr::showAFG()
{
    // FIRST集 用于中间生成
    // map<char, set<char>> FIRST;
    // ACTION表 int + char -> char + int
    // map<pair<int, char>, pair<actionState, int>> ACTION;
    // GOTO表 int + char -> int
    // map<pair<int, char>, int> GOTO;
    //     enum actionState {
    //     acc = 0,
    //     shift,
    //     reduce,
    //     err,
    // };

    // First:
    G.showFinal();

    cout << "FIRST : " << endl;
    output_FIRST << "FIRST : " << endl;

    map<char, set<char>>::iterator itFirst = FIRST.begin();
    for (; itFirst != FIRST.end(); itFirst++) {
        cout << (*itFirst).first << " : ";
        output_FIRST << (*itFirst).first << " : ";
        set<char>::iterator itFirst2 = (*itFirst).second.begin();
        for (; itFirst2 != (*itFirst).second.end(); itFirst2++) {
            cout << " " << (*itFirst2);
            output_FIRST << " " << (*itFirst2);
        }
        cout << endl;
        output_FIRST << endl;
    }
    cout << "ACTION : acc 0 shift 1 reduce 2" << endl;
    output_ACTION << "ACTION : acc 0 shift 1 reduce 2" << endl;

    map<pair<int, char>, pair<actionState, int>>::iterator itAction =
        ACTION.begin();
    for (; itAction != ACTION.end(); itAction++) {
        cout << (*itAction).first.first << " " << (*itAction).first.second
             << " " << (*itAction).second.first << " "
             << (*itAction).second.second << endl;
        output_ACTION << (*itAction).first.first << " "
                      << (*itAction).first.second << " "
                      << (*itAction).second.first << " "
                      << (*itAction).second.second << endl;
    }

    cout << "GOTO : " << endl;
    output_GOTO << "GOTO : " << endl;

    map<pair<int, char>, int>::iterator itGoto = GOTO.begin();
    for (; itGoto != GOTO.end(); itGoto++) {
        if (isupper((*itGoto).first.second)) {
            cout << (*itGoto).first.first << " " << (*itGoto).first.second
                 << " " << (*itGoto).second << endl;
            output_GOTO << (*itGoto).first.first << " "
                        << (*itGoto).first.second << " " << (*itGoto).second
                        << endl;
        }
    }
}

/**
 * @description: 打开文件
 * @param {type}
 * @return:
 */
void LfileOpen()
{
    output_ACTION.open("ACTION.txt");
    output_FIRST.open("FIRST.txt");
    output_PARSER.open("PARSER.txt");
    output_GOTO.open("GOTO.txt");
}

/**
 * @description: 关闭文件
 * @param {type}
 * @return:
 */
void LfileClose()
{
    output_ACTION.close();
    output_FIRST.close();
    output_PARSER.close();
    output_GOTO.close();
}

/**
 * @description: 判断是否为界符
 * @param {type}
 * @return:
 */

bool isDelimiterS(char a)
{
    for (int i = 0; i < delimiterNumS; i++) {
        if (a == delimiterS[i]) {
            return true;
        }
    }
    return false;
}
